package com.example.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.Coupons.service.impl.CouponService;
import com.example.Utility.RedisUtils;
import com.example.Utility.objIsNull;
import com.example.Utility.publicUtils;
import com.example.entity.OrderMessage;
import com.example.entity.lordOrder;
import com.example.mapper.lordOrderMapper;
import com.example.service.*;
import com.example.user.UserIntegral.service.impl.IntegralService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;


/**
 * @author Super
 */
@Service
@Slf4j
public class lordOrderServiceImpl extends ServiceImpl<lordOrderMapper, lordOrder> implements lordOrderService {

    @Resource
    private OrderMessageSrvice orderMessageSrvice;
    @Autowired

    @Resource
    private GoodsService goodsService;
    @Autowired

    @Resource
    private IntegralService integralService;

    @Resource
    private CouponService couponService;

    @Autowired
    private ShoppingCarService shoppingCarService;
    // 分布式锁
    @Resource
    private RedissonClient redissonClient;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private UsermessageService usermessageService;

    @Autowired
    private lordOrderService lordOrderService;


    @Transactional
    public lordOrder createOrder(Object obj) {
        if (objIsNull.isNull(obj)) {
            log.error("商品对象为空");
            throw new RuntimeException("商品对象为空");
        }
        /**
         * 创建订单对象
         */
        String dates = obj.toString();
        String value = dates.substring(dates.indexOf("["), dates.lastIndexOf("]") + 1);
        lordOrder lordOrder = new lordOrder();
//        获取到商品信息
        List<OrderMessage> orderMessageList = JSONArray.parseArray(value, OrderMessage.class);
//       商品集合
        lordOrder.setOrderMessages(orderMessageList);
//        订单状态
        // 默认待支付
        lordOrder.setState(0);
//        订单号
        lordOrder.setOrderNo(publicUtils.generateOrderNumber("0001"));
        String openid = orderMessageList.get(0).getOpenid();
        lordOrder.setOpenid(openid);
//        优惠券的集合
        //      查找优惠券
        try {
            lordOrder.setCouponList(couponService.getCouponList(orderMessageList));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

//     获取用户余额
        lordOrder.setRemainingSum(usermessageService.getUserMsg(openid).getMoney());

//        获取商品总价
        lordOrder.setTotalPrice(publicUtils.getCommodityListAmount(orderMessageList));
        lordOrderService.save(lordOrder);
        for (OrderMessage message : orderMessageList) message.setMId(lordOrder.getId());
//        批量修改商品MID
        orderMessageSrvice.saveBatch(orderMessageList);
        if (!objIsNull.isNull(lordOrder)) {
            /**
             * 把订单数据放在缓存中 5分钟消失
             */
            redisUtils.redisAdd(lordOrder.getOrderNo(), lordOrder, 30, TimeUnit.DAYS);
        }
        return lordOrder;
    }

    @Override
    public Boolean commentAdd(lordOrder lordOrder) {
        if (!redisUtils.haveKey(lordOrder.getOrderNo())) {
            throw new RuntimeException("缓存");
        }
        lordOrder redisObject = redisUtils.getRedisObject(lordOrder.getOrderNo(), lordOrder.class);
        redisObject.setDiscountsId(lordOrder.getDiscountsId());
        // 实现分布式锁
        RLock rLock = redissonClient.getLock("lock_" + lordOrder.getOpenid());
        try {
            // 加锁,可以指定锁定时间
            rLock.lock(30, TimeUnit.SECONDS);
            //            下单信息
            log.info(lordOrder.getOpenid() + "获得锁");
            //      优惠券Id 优惠券处理
            redisObject.setTotalPrice(redisObject.getTotalPrice().subtract(couponService.dealCoupon(redisObject)));
            // 地址id
            redisObject.setAddressId(lordOrder.getAddressId());
            //            支付方式
            redisObject.setModeOfPayment(lordOrder.getModeOfPayment());
            //            用户留言
            redisObject.setIssue(lordOrder.getIssue());
//            支付时间
            redisObject.setPayTime(LocalDateTime.now());
//            待发货
            redisObject.setState(1);
/**
 * 更新库存
 */
            // 如果下单成功执行库存删减
            if (!goodsService.deleteShopping(redisObject.getOrderMessages()))
                throw new RuntimeException("库存更新失败！！！");
            //     添加积分
            if (!integralService.AddIntegral(redisObject.getOrderMessages()))
                throw new RuntimeException("积分添加失败");
            // 购物车删除
            if (!shoppingCarService.deleteShoppingAll(redisObject.getOrderMessages()))
                throw new RuntimeException("购物车删除失败");
            UpdateWrapper<lordOrder> lordOrderLambdaQueryWrapper = new UpdateWrapper<>();
            lordOrderLambdaQueryWrapper.eq("order_no", lordOrder.getOrderNo());
            lordOrderService.update(redisObject, lordOrderLambdaQueryWrapper);
            redisUtils.delete(lordOrder.getOrderNo());
            log.info(lordOrder.getOpenid() + "业务结束");
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            // 释放锁（解锁）
            log.info(lordOrder.getOpenid() + "释放锁");
            rLock.unlock();   // 释放锁
        }
        return true;
    }
}
